package com.buaa.divinationmaster.core.database.initializer;

import android.content.Context;
import android.util.Log;

import com.buaa.divinationmaster.core.database.DivinationDatabase;
import com.buaa.divinationmaster.core.database.dao.TarotCardDao;
import com.buaa.divinationmaster.core.database.entities.TarotCard;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 数据库初始化器
 * 负责初始化数据库数据，包括塔罗牌数据的加载和预置
 */
public class DatabaseInitializer {
    
    private static final String TAG = "DatabaseInitializer";
    
    private final Context context;
    private final DivinationDatabase database;
    private final ExecutorService executorService;
    
    // 单例模式
    private static volatile DatabaseInitializer instance;
    
    private DatabaseInitializer(Context context) {
        this.context = context.getApplicationContext();
        this.database = DivinationDatabase.getInstance(this.context);
        this.executorService = Executors.newSingleThreadExecutor();
    }
    
    /**
     * 获取单例实例
     */
    public static DatabaseInitializer getInstance(Context context) {
        if (instance == null) {
            synchronized (DatabaseInitializer.class) {
                if (instance == null) {
                    instance = new DatabaseInitializer(context);
                }
            }
        }
        return instance;
    }
    
    /**
     * 初始化数据库
     */
    public void initializeDatabase(InitializationCallback callback) {
        executorService.execute(() -> {
            try {
                Log.d(TAG, "开始初始化数据库...");
                
                // 检查是否需要初始化
                if (isDatabaseInitialized()) {
                    Log.d(TAG, "数据库已初始化，跳过初始化过程");
                    if (callback != null) {
                        callback.onSuccess("数据库已初始化");
                    }
                    return;
                }
                
                // 初始化塔罗牌数据
                initializeTarotCards(callback);
                
            } catch (Exception e) {
                Log.e(TAG, "数据库初始化失败", e);
                if (callback != null) {
                    callback.onError("数据库初始化失败: " + e.getMessage());
                }
            }
        });
    }
    
    /**
     * 初始化塔罗牌数据
     */
    private void initializeTarotCards(InitializationCallback callback) {
        try {
            // 使用内置塔罗牌数据初始化
            List<TarotCard> basicTarotCards = createBasicTarotCards();
            
            if (callback != null) {
                callback.onProgress("初始化塔罗牌数据", basicTarotCards.size(), basicTarotCards.size());
            }
            
            // 将数据保存到数据库
            saveTarotCardsToDatabase(basicTarotCards, callback);
            
        } catch (Exception e) {
            Log.e(TAG, "初始化塔罗牌数据失败", e);
            if (callback != null) {
                callback.onError("初始化塔罗牌数据失败: " + e.getMessage());
            }
        }
    }
    
    /**
     * 将塔罗牌数据保存到数据库
     */
    private void saveTarotCardsToDatabase(List<TarotCard> cards, InitializationCallback callback) {
        executorService.execute(() -> {
            try {
                TarotCardDao tarotCardDao = database.tarotCardDao();
                
                Log.d(TAG, "开始保存塔罗牌数据: " + cards.size() + " 张牌");
                
                // 批量插入塔罗牌数据
                for (int i = 0; i < cards.size(); i++) {
                    TarotCard card = cards.get(i);
                    tarotCardDao.insert(card);
                    
                    // 报告进度
                    if (callback != null && i % 10 == 0) {
                        callback.onProgress("保存塔罗牌数据", i + 1, cards.size());
                    }
                }
                
                Log.d(TAG, "塔罗牌数据保存完成: " + cards.size() + " 张牌");
                
                // 验证数据完整性
                validateTarotData(callback);
                
            } catch (Exception e) {
                Log.e(TAG, "保存塔罗牌数据失败", e);
                if (callback != null) {
                    callback.onError("保存塔罗牌数据失败: " + e.getMessage());
                }
            }
        });
    }
    
    /**
     * 验证塔罗牌数据的完整性
     */
    private void validateTarotData(InitializationCallback callback) {
        try {
            TarotCardDao tarotCardDao = database.tarotCardDao();
            
            int totalCards = tarotCardDao.getCardCount();
            int majorCount = tarotCardDao.getMajorArcanaCount();
            int minorCount = tarotCardDao.getMinorArcanaCount();
            
            Log.d(TAG, "数据验证: 总牌数=" + totalCards + ", 大阿卡纳=" + majorCount + ", 小阿卡纳=" + minorCount);
            
            // 验证数量
            boolean isValid = (majorCount == 22) && (totalCards >= 22);
            
            if (isValid) {
                markDatabaseAsInitialized();
                Log.d(TAG, "数据库初始化成功");
                
                if (callback != null) {
                    callback.onSuccess("数据库初始化成功，共加载 " + totalCards + " 张塔罗牌");
                }
            } else {
                String error = "数据完整性验证失败: 期望22张大阿卡纳，实际" + majorCount + "张";
                Log.e(TAG, error);
                
                if (callback != null) {
                    callback.onError(error);
                }
            }
            
        } catch (Exception e) {
            Log.e(TAG, "数据验证失败", e);
            if (callback != null) {
                callback.onError("数据验证失败: " + e.getMessage());
            }
        }
    }
    
    /**
     * 检查数据库是否已初始化
     */
    private boolean isDatabaseInitialized() {
        try {
            TarotCardDao tarotCardDao = database.tarotCardDao();
            return tarotCardDao.isDataInitialized();
        } catch (Exception e) {
            Log.e(TAG, "检查数据库初始化状态失败", e);
            return false;
        }
    }
    
    /**
     * 标记数据库已初始化
     */
    private void markDatabaseAsInitialized() {
        try {
            // 可以在这里设置一个标记，比如插入一个特殊记录
            // 或者使用SharedPreferences来记录初始化状态
            
            android.content.SharedPreferences prefs = context.getSharedPreferences(
                    "divination_db", Context.MODE_PRIVATE);
            prefs.edit()
                 .putBoolean("database_initialized", true)
                 .putLong("initialized_time", System.currentTimeMillis())
                 .apply();
            
            Log.d(TAG, "数据库已标记为初始化完成");
            
        } catch (Exception e) {
            Log.e(TAG, "标记数据库初始化状态失败", e);
        }
    }
    
    /**
     * 重置数据库（清空所有数据）
     */
    public void resetDatabase(InitializationCallback callback) {
        executorService.execute(() -> {
            try {
                Log.d(TAG, "开始重置数据库...");
                
                // 清空塔罗牌表
                TarotCardDao tarotCardDao = database.tarotCardDao();
                tarotCardDao.deleteAll();
                
                // 清空初始化标记
                android.content.SharedPreferences prefs = context.getSharedPreferences(
                        "divination_db", Context.MODE_PRIVATE);
                prefs.edit().clear().apply();
                
                Log.d(TAG, "数据库重置完成");
                
                if (callback != null) {
                    callback.onSuccess("数据库重置完成");
                }
                
            } catch (Exception e) {
                Log.e(TAG, "数据库重置失败", e);
                if (callback != null) {
                    callback.onError("数据库重置失败: " + e.getMessage());
                }
            }
        });
    }
    
    /**
     * 获取数据库状态信息
     */
    public void getDatabaseStatus(StatusCallback callback) {
        executorService.execute(() -> {
            try {
                DatabaseStatus status = new DatabaseStatus();
                
                TarotCardDao tarotCardDao = database.tarotCardDao();
                status.isInitialized = isDatabaseInitialized();
                status.totalTarotCards = tarotCardDao.getCardCount();
                status.majorArcanaCount = tarotCardDao.getMajorArcanaCount();
                status.minorArcanaCount = tarotCardDao.getMinorArcanaCount();
                
                // 获取初始化时间
                android.content.SharedPreferences prefs = context.getSharedPreferences(
                        "divination_db", Context.MODE_PRIVATE);
                status.initializationTime = prefs.getLong("initialized_time", 0);
                
                if (callback != null) {
                    callback.onStatusReceived(status);
                }
                
            } catch (Exception e) {
                Log.e(TAG, "获取数据库状态失败", e);
                if (callback != null) {
                    callback.onError("获取数据库状态失败: " + e.getMessage());
                }
            }
        });
    }
    
    /**
     * 释放资源
     */
    public void destroy() {
        if (executorService != null && !executorService.isShutdown()) {
            executorService.shutdown();
        }
    }
    
    // ========== 回调接口 ==========
    
    /**
     * 初始化回调接口
     */
    public interface InitializationCallback {
        void onProgress(String phase, int current, int total);
        void onSuccess(String message);
        void onError(String error);
    }
    
    /**
     * 状态回调接口
     */
    public interface StatusCallback {
        void onStatusReceived(DatabaseStatus status);
        void onError(String error);
    }
    
    // ========== 数据类 ==========
    
    /**
     * 数据库状态信息
     */
    public static class DatabaseStatus {
        public boolean isInitialized = false;
        public int totalTarotCards = 0;
        public int majorArcanaCount = 0;
        public int minorArcanaCount = 0;
        public long initializationTime = 0;
        
        @Override
        public String toString() {
            return "DatabaseStatus{" +
                    "isInitialized=" + isInitialized +
                    ", totalTarotCards=" + totalTarotCards +
                    ", majorArcanaCount=" + majorArcanaCount +
                    ", minorArcanaCount=" + minorArcanaCount +
                    ", initializationTime=" + initializationTime +
                    '}';
        }
    }
    
    /**
     * 创建基础塔罗牌数据
     */
    private List<TarotCard> createBasicTarotCards() {
        List<TarotCard> cards = new java.util.ArrayList<>();
        
        // 大阿卡纳牌 (22张)
        String[] majorArcana = {
            "愚者", "魔术师", "女祭司", "女皇", "皇帝", "教皇", "恋人", "战车",
            "力量", "隐者", "命运之轮", "正义", "吊人", "死神", "节制", "恶魔",
            "高塔", "星星", "月亮", "太阳", "审判", "世界"
        };
        
        for (int i = 0; i < majorArcana.length; i++) {
            TarotCard card = new TarotCard();
            card.id = i + 1;
            card.nameZh = majorArcana[i];
            card.nameEn = "Major Arcana " + (i + 1);
            card.type = "major";
            card.number = i;
            card.uprightKeywords = "正向含义";
            card.reversedKeywords = "逆向含义";
            card.uprightMeaning = "正位解读";
            card.reversedMeaning = "逆位解读";
            card.element = "通用";
            card.imagePath = "tarot_major_" + i + ".png";
            cards.add(card);
        }
        
        return cards;
    }
}
